﻿// Decompiled with JetBrains decompiler
// Type: Netick.NetickUtils
// Assembly: Netick, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 6726ECA1-C773-4CF7-8952-E81B30D93B52
// Assembly location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.dll
// XML documentation location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.xml

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;

#nullable disable
namespace Netick;

public static class NetickUtils
{
  private static readonly int[] DeBruijnLookup = new int[32 /*0x20*/]
  {
    0,
    9,
    1,
    10,
    13,
    21,
    2,
    29,
    11,
    14,
    16 /*0x10*/,
    18,
    22,
    25,
    3,
    30,
    8,
    12,
    20,
    28,
    15,
    17,
    24,
    7,
    19,
    27,
    23,
    6,
    26,
    5,
    4,
    31 /*0x1F*/
  };
  private static readonly int[] LookupTable = new int[64 /*0x40*/]
  {
    63 /*0x3F*/,
    0,
    58,
    1,
    59,
    47,
    53,
    2,
    60,
    39,
    48 /*0x30*/,
    27,
    54,
    33,
    42,
    3,
    61,
    51,
    37,
    40,
    49,
    18,
    28,
    20,
    55,
    30,
    34,
    11,
    43,
    14,
    22,
    4,
    62,
    57,
    46,
    52,
    38,
    26,
    32 /*0x20*/,
    41,
    50,
    36,
    17,
    19,
    29,
    10,
    13,
    21,
    56,
    45,
    25,
    31 /*0x1F*/,
    35,
    16 /*0x10*/,
    9,
    12,
    44,
    24,
    15,
    8,
    23,
    7,
    6,
    5
  };

  internal static int FastLog2(ulong value)
  {
    value |= value >> 1;
    value |= value >> 2;
    value |= value >> 4;
    value |= value >> 8;
    value |= value >> 16 /*0x10*/;
    value |= value >> 32 /*0x20*/;
    return NetickUtils.LookupTable[checked ((ulong) (unchecked ((long) value - (long) (value >> 1) * 571347909858961602L) >>> 58))];
  }

  internal static int RoundToNearestEven(float value)
  {
    return (int) ((double) MathF.Truncate(value) + (double) MathF.Truncate(value) % 2.0);
  }

  internal static int RoundToPowerOfTwo(int v)
  {
    --v;
    v |= v >> 1;
    v |= v >> 2;
    v |= v >> 4;
    v |= v >> 8;
    v |= v >> 16 /*0x10*/;
    ++v;
    return v;
  }

  internal static int FastLog2(uint v)
  {
    v |= v >> 1;
    v |= v >> 2;
    v |= v >> 4;
    v |= v >> 8;
    v |= v >> 16 /*0x10*/;
    return NetickUtils.DeBruijnLookup[(int) (v * 130329821U >> 27)];
  }

  internal static int GetByteIndexWithinWord(int byteIndex)
  {
    int num = byteIndex % 4;
    return num != 0 ? 4 - num : 0;
  }

  public static int GetWordSize(int byteSize)
  {
    return Math.Max(1, (int) MathF.Ceiling((float) byteSize / 4f));
  }

  public static int GetWordSize(int byteSize, int alignment)
  {
    float num = (float) alignment;
    return Math.Max(1, (int) MathF.Ceiling((float) byteSize / num));
  }

  public static int Ceiling(int v) => Math.Max(1, (int) MathF.Ceiling((float) v));

  [MethodImpl(MethodImplOptions.AggressiveInlining)]
  public static int PowerOfTwo(int depth) => (int) Math.Pow(2.0, (double) depth);

  [MethodImpl(MethodImplOptions.AggressiveInlining)]
  public static float Lerp(float a, float b, float t) => a + (b - a) * NetickUtils.Clamp01(t);

  [MethodImpl(MethodImplOptions.AggressiveInlining)]
  public static float InverseLerp(float a, float b, float value)
  {
    return (double) a != (double) b ? NetickUtils.Clamp01((float) (((double) value - (double) a) / ((double) b - (double) a))) : 0.0f;
  }

  [MethodImpl(MethodImplOptions.AggressiveInlining)]
  public static float Clamp01(float a) => Math.Clamp(a, 0.0f, 1f);

  [MethodImpl(MethodImplOptions.AggressiveInlining)]
  internal static unsafe float GetFloat(int* data, float precision)
  {
    return (double) precision != -1.0 ? (float) *data * precision : *(float*) data;
  }

  [MethodImpl(MethodImplOptions.AggressiveInlining)]
  internal static unsafe void SetFloat(int* data, float value, float precisionInverse)
  {
    if ((double) precisionInverse == -1.0)
      *(float*) data = value;
    else
      *data = (double) value > 0.0 ? (int) ((double) value * (double) precisionInverse + 0.5) : (int) ((double) value * (double) precisionInverse - 0.5);
  }

  public static unsafe string LoadStringFromPtr(StringBuilder cache, int* ptr, int charCount)
  {
    if (cache == null)
      cache = new StringBuilder(charCount * 10);
    cache.Clear();
    char* chPtr = (char*) ptr;
    for (int index = 0; index < charCount && chPtr[index] != char.MinValue; ++index)
      cache.Append(chPtr[index]);
    return cache.ToString();
  }

  public static unsafe void SetPtrString(
    INetickNetworkScript beh,
    string newVal,
    int* ptr,
    int charCount,
    int hasOnChanged,
    int isInputSourceOnly)
  {
    int wordSize = NetickUtils.GetWordSize(Math.Min(charCount, newVal.Length) * 2);
    if (newVal == "" || newVal == null || newVal == " ")
      newVal = " ";
    int* data = stackalloc int[wordSize];
    char* chPtr = (char*) data;
    for (int index = 0; index < newVal.Length; ++index)
      chPtr[index] = newVal[index];
    Entity.InternalDirtify(beh, data, ptr, wordSize, hasOnChanged, isInputSourceOnly);
  }

  public static string GetMethodName(MethodInfo method)
  {
    string methodName = method.DeclaringType.FullName + method.Name;
    foreach (ParameterInfo parameter in method.GetParameters())
      methodName += parameter.ParameterType.Name;
    return methodName;
  }

  public static List<Type> GetAllSubclassOf(Type parent)
  {
    List<Type> allSubclassOf = new List<Type>();
    foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
    {
      foreach (Type type in assembly.GetTypes())
      {
        if (type.IsSubclassOf(parent))
          allSubclassOf.Add(type);
      }
    }
    return allSubclassOf;
  }

  public static int GetStableHashCode(this string str)
  {
    int num1 = 5381;
    int num2 = num1;
    for (int index = 0; index < str.Length && str[index] != char.MinValue; index += 2)
    {
      num1 = (num1 << 5) + num1 ^ (int) str[index];
      if (index != str.Length - 1 && str[index + 1] != char.MinValue)
        num2 = (num2 << 5) + num2 ^ (int) str[index + 1];
      else
        break;
    }
    return num1 + num2 * 1566083941;
  }

  internal static void RemoveUnordered(this List<Entity> list, Entity item)
  {
    for (int index = 0; index < list.Count; ++index)
    {
      if (list[index] == item)
      {
        list[index] = list[list.Count - 1];
        list.RemoveAt(list.Count - 1);
        break;
      }
    }
  }

  internal static void RemoveUnordered(this List<NetworkPlayerId> list, NetworkPlayerId item)
  {
    for (int index = 0; index < list.Count; ++index)
    {
      if (list[index] == item)
      {
        list[index] = list[list.Count - 1];
        list.RemoveAt(list.Count - 1);
        break;
      }
    }
  }
}
